package com.yueyang.sojourn.server.service.sojourn.project;

import com.alibaba.fastjson.JSON;
import com.yueyang.sojourn.server.common.baymax.web.result.JAssert;
import com.yueyang.sojourn.server.model.dto.AddProjectDto;
import com.yueyang.sojourn.server.model.dto.EditProjectDto;
import com.yueyang.sojourn.server.model.dto.GeoLocationDto;
import com.yueyang.sojourn.server.model.enums.OperStatusEnum;
import com.yueyang.sojourn.server.model.enums.StatusEnum;
import com.yueyang.sojourn.server.model.po.AttachDetail;
import com.yueyang.sojourn.server.model.po.SojournGeoLocation;
import com.yueyang.sojourn.server.model.po.SojournProject;
import com.yueyang.sojourn.server.model.po.SojournProjectPic;
import com.yueyang.sojourn.server.service.attachdetail.AttachDetailService;
import com.yueyang.sojourn.server.service.sojourn.geolocation.SojournGeoLocationService;
import com.yueyang.sojourn.server.service.sojourn.projectpic.SojournProjectPicService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author yemingxing
 * @summary 项目 写service
 * @Copyright (c) 2020, Yueyang Group All Rights Reserved.
 * @since 2020-02-15
 */
@Service
public class WriteProjectService {

    @Resource
    private SojournProjectMapper sojournProjectMapper;

    @Autowired
    private ReadProjectService readProjectService;

    @Autowired
    private AttachDetailService attachDetailService;

    @Autowired
    private SojournProjectPicService sojournProjectPicService;

    @Autowired
    private SojournGeoLocationService sojournGeoLocationService;

    /**
     * 新建项目
     *
     * @param projectDto 项目dto
     */
    @Transactional(rollbackFor = Exception.class)
    public Long addProject(long loginUserId, AddProjectDto projectDto) {

        //todo-ymx 电话号码加密
        SojournProject project = new SojournProject();
        BeanUtils.copyProperties(projectDto, project);
        // 主图片
        long attachId = attachDetailService.addReturnId(loginUserId, projectDto.getHomePic());
        project.setHomeAttachId(attachId);
        project.setBasicFacility(JSON.toJSONString(ListUtils.emptyIfNull(projectDto.getBasicFacility())));
        project.setCatering(JSON.toJSONString(ListUtils.emptyIfNull(projectDto.getCatering())));
        project.setRecreation(JSON.toJSONString(ListUtils.emptyIfNull(projectDto.getRecreation())));
        project.setOperStatus(OperStatusEnum.TO_BE_OPENED.getCode());
        project.setStatus(StatusEnum.VALID.getCode());
        Date nowDate = new Date();
        project.setCreator(loginUserId);
        project.setCreatedTime(nowDate);
        project.setUpdator(loginUserId);
        project.setUpdatedTime(nowDate);
        sojournProjectMapper.insert(project);

        // 地理位置信息
        SojournGeoLocation geoLocation = dto2po(project, nowDate, projectDto.getLocation());
        sojournGeoLocationService.insert(geoLocation);

        //其他图片
        List<AttachDetail> othersPic = projectDto.getOthersPic().stream().map(attachDto -> {
            AttachDetail attachDetail = new AttachDetail();
            BeanUtils.copyProperties(attachDto, attachDetail);
            attachDetail.setStatus(StatusEnum.VALID.getCode());
            attachDetail.setCreator(loginUserId);
            attachDetail.setCreatedTime(new Date());
            return attachDetail;
        }).collect(Collectors.toList());
        attachDetailService.insertList(othersPic);
        List<SojournProjectPic> projectPics = formatSojournProjectPics(loginUserId, project, nowDate, othersPic);
        sojournProjectPicService.insertList(projectPics);
        return project.getId();
    }

    /**
     * 编辑项目信息
     *
     * @param loginUserId
     * @param projectDto
     */
    @Transactional(rollbackFor = Exception.class)
    public void editProject(long loginUserId, EditProjectDto projectDto) {
        SojournProject projectBefore = sojournProjectMapper.selectByPrimaryKey(projectDto.getId());
        if (Objects.isNull(projectBefore)) {
            JAssert.justFailed("不存在的项目id: " + projectDto.getId());
        }
        //todo-ymx 电话号码加密
        SojournProject project = new SojournProject();
        BeanUtils.copyProperties(projectDto, project);
        // 主图片
        Long attachId;
        if (Objects.nonNull(projectDto.getHomePic())) {
            attachId = attachDetailService.addReturnId(loginUserId, projectDto.getHomePic());
        } else {
            attachId = null;
        }
        project.setHomeAttachId(attachId);
        project.setBasicFacility(JSON.toJSONString(ListUtils.emptyIfNull(projectDto.getBasicFacility())));
        project.setCatering(JSON.toJSONString(ListUtils.emptyIfNull(projectDto.getCatering())));
        project.setRecreation(JSON.toJSONString(ListUtils.emptyIfNull(projectDto.getRecreation())));
        project.setUpdator(loginUserId);
        Date nowDate = new Date();
        project.setUpdatedTime(nowDate);
        sojournProjectMapper.updateByPrimaryKeySelective(project);

        // 地理位置信息
        if (Objects.nonNull(projectDto.getLocation())) {
            sojournGeoLocationService.invalidByProjectId(projectDto.getId());

            SojournGeoLocation geoLocation = dto2po(project, nowDate, projectDto.getLocation());
            sojournGeoLocationService.insert(geoLocation);
        }

        //其他图片
        if (CollectionUtils.isNotEmpty(projectDto.getOthersPic())) {
            List<AttachDetail> othersPic = projectDto.getOthersPic().stream().map(attachDto -> {
                AttachDetail attachDetail = new AttachDetail();
                BeanUtils.copyProperties(attachDto, attachDetail);
                attachDetail.setStatus(StatusEnum.VALID.getCode());
                attachDetail.setCreator(loginUserId);
                attachDetail.setCreatedTime(new Date());
                return attachDetail;
            }).collect(Collectors.toList());
            attachDetailService.insertList(othersPic);

            sojournProjectPicService.invalidByProjectId(loginUserId, projectDto.getId());

            List<SojournProjectPic> projectPics = this.formatSojournProjectPics(loginUserId, project, nowDate, othersPic);
            sojournProjectPicService.insertList(projectPics);
        }
    }

    private SojournGeoLocation dto2po(SojournProject project, Date nowDate, GeoLocationDto location) {
        SojournGeoLocation geoLocation = new SojournGeoLocation();
        geoLocation.setProjectId(project.getId());
        geoLocation.setLongitude(new BigDecimal(location.getLongitude()));
        geoLocation.setLatitude(new BigDecimal(location.getLatitude()));
        geoLocation.setAddress(location.getAddress());
        geoLocation.setStatus(StatusEnum.VALID.getCode());
        geoLocation.setCreatedTime(nowDate);
        geoLocation.setUpdatedTime(nowDate);
        return geoLocation;
    }

    private List<SojournProjectPic> formatSojournProjectPics(long loginUserId, SojournProject project, Date nowDate, List<AttachDetail> othersPic) {
        return othersPic.stream().map(attachDetail -> {
            SojournProjectPic projectPic = new SojournProjectPic();
            projectPic.setAttachId(attachDetail.getId());
            projectPic.setProjectId(project.getId());
            projectPic.setStatus(StatusEnum.VALID.getCode());
            projectPic.setCreator(loginUserId);
            projectPic.setCreatedTime(nowDate);
            projectPic.setUpdator(loginUserId);
            projectPic.setUpdatedTime(nowDate);
            return projectPic;
        }).collect(Collectors.toList());
    }

    public void editOperStatus(long loginUserId, Long projectId, Integer operStatus) {
        if (Objects.isNull(OperStatusEnum.ofCode(operStatus))) {
            JAssert.justFailed("operStatus枚举值错误");
        }
        SojournProject sojournProject = new SojournProject();
        sojournProject.setId(projectId);
        sojournProject.setUpdator(loginUserId);
        sojournProject.setUpdatedTime(new Date());
        sojournProject.setOperStatus(operStatus);
        sojournProjectMapper.updateByPrimaryKeySelective(sojournProject);
    }
}
